export default class Bezier {
    constructor(start, c1, c2, end, style) {
        this.start = start;
        this.c1 = c1;
        this.c2 = c2;
        this.end = end;
        style = Object.assign({
            color: "#ffffff",
            lineWidth: 1,
            shadowColor: "#ffffff",
            shadowBlur: 0,
            shadowOffsetX: 0,
            shadowOffsetY: 0
        }, style);
        Object.assign(this, style);
    }

    draw(ctx, debug) {
        const that = this;
        ctx.beginPath();
        ctx.shadowBlur = this.shadowBlur;
        ctx.shadowOffsetX = this.shadowOffsetX;
        ctx.shadowOffsetY = this.shadowOffsetY;
        ctx.shadowColor = this.shadowColor;
        ctx.strokeStyle = this.color;
        ctx.lineWidth = this.lineWidth;
        ctx.moveTo(that.start[0], that.start[1]);
        ctx.bezierCurveTo(that.c1[0], that.c1[1], that.c2[0], that.c2[1], that.end[0], that.end[1]);
        ctx.stroke();
        ctx.closePath();
        ctx.shadowBlur = 0;

        if (debug) {
            ctx.fillStyle = "#00ff00";
            drawPoint(ctx, that.start, 2);
            drawPoint(ctx, that.end, 2);
        }
    }

    getPos(t) {
        if (t > 1 || t < 0) {
            return null;
        }

        const that = this;
        const pow = Math.pow;
        const a = pow(1 - t, 3),
            b = 3 * t * pow(1 - t, 2),
            c = 3 * pow(t, 2) * (1 - t),
            d = pow(t, 3);
        const x = a * that.start[0] + b * that.c1[0] + c * that.c2[0] + d * that.end[0];
        const y = a * that.start[1] + b * that.c1[1] + c * that.c2[1] + d * that.end[1];
        return [x, y];
    }
}


function drawPoint(ctx, p, size) {
    ctx.beginPath();
    ctx.arc(p[0], p[1], size, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();
}

function drawLine(ctx, p1, p2) {
    ctx.beginPath();
    ctx.moveTo(p1[0], p1[1]);
    ctx.lineTo(p2[0], p2[1]);
    ctx.stroke();
    ctx.closePath();
}